#include "factory.h"
//线程池初始化
int factory_init(Factory_t *pf,int thread_num,int capacity)
{
    que_init(&pf->que,capacity);//队列初始化
    int ret=pthread_cond_init(&pf->cond,NULL);//条件变量初始化
    THREAD_ERR_CHECK(ret,"pthread_cond_init");
    pf->pthid=(pthread_t *)calloc(thread_num,sizeof(pthread_t));//为线程id申请空间
    pf->start_flag=0;//线程池启动标志设为0
    return 0;
}
//线程池启动
int factory_start(Factory_t *pf,int thread_num)
{
    if(!pf->start_flag)//如果线程池没启动
    {
        int i;
        for(i=0;i<thread_num;i++)
        {
            pthread_create(pf->pthid+1,NULL,thread_handle,pf);
        }
        pf->start_flag=1;
    }
}

//释放锁资源
void cleanup(void* p)
{
    pthread_mutex_unlock((pthread_mutex_t*)p);
}
//子线程流程
void* thread_handle(void* p)
{
    Factory_t* pf=(Factory_t*)p;
    train_state_t *pc=(train_state_t*)p;
    Client_State_t *pnew=(Client_State_t *)p;
    pQue_t pq=&(pf->que);//让一个队列指针指向队列
    pNode_t pcur=NULL;//取队列结点
    //建立puts/gets专属传输路线
    int tran_fd;
    while(1)
    {
        pthread_mutex_lock(&pq->mutex);
        pthread_cleanup_push(cleanup,&pq->mutex);
        if(0==pq->que_size)//如果队列为空
        {
            pthread_cond_wait(&pf->cond,&pq->mutex);
        }
        que_get(pq,&pcur);////取队列结点
        pthread_cleanup_pop(1);//直接通过pop来解锁
        if(pcur)//pcur不为NULL代表拿到了结点
        {
            tran_fd=socket(AF_INET,SOCK_STREAM,0);
            int ret,reuse=1;
            struct sockaddr_in my_addr;
            ret=setsockopt(tran_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int));
            memset(&my_addr,0,sizeof(struct sockaddr_in));
            my_addr.sin_family = AF_INET;
            my_addr.sin_port=htons(atoi(pnew->port));
            my_addr.sin_addr.s_addr=inet_addr(pnew->ip);
            ret=connect(tran_fd,(struct sockaddr*)&my_addr,sizeof(my_addr));
            //ERROR_CHECK(ret,-1,"connect");
            if(ret==-1)
            {
                printf("Connect fail!\n");
            }
            ret=client_token(tran_fd,pc,pnew->token);
            if(-1==ret)//token验证失败
            {
                printf("Validation fail!\n");
                return 0;
            }
            else{
                if(pc->cmd_type==PUTS)
                {
                    do_puts(tran_fd,pc,pnew);
                }
                else{
                    do_gets(tran_fd,pc,pnew);
                }
            }
            free(pcur);
            pcur=NULL;
            close(tran_fd);
            pthread_exit(NULL);
            continue;
        }
    }
}